package com.self.audiocapture;

import android.app.Instrumentation;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;

import com.self.audiocapture.databinding.RecordScreenBinding;
import com.self.audiocapture.move.IMoveControl;
import com.self.audiocapture.move.MoveControl;
import com.self.audiocapture.move.MoveManager;


/**
 * @author huang
 */
public class FloatBarManager extends Service {
    private static final String TAG = "FloatBarManager";
    private static final int UPDATE_MESSAGE_STOP_RESULT = 0x01;
    private static final String STOP_RESULT = "stop_result";
    private static final int UPDATE_TIME = 0x02;
    private static final int UPDATE_TIME_RESET = 0x03;
    private static final int SHOW_VIDEO_SAVE_PATH = 0x04;
    private static final String SAVE_PATH_PRE = "/sdcard/Movies/";

    private WindowManager wm;
    private WindowManager.LayoutParams layoutParams;
    private LinearLayout linearLayout;
    private RecordScreenBinding binding;
    private Handler handler;
    private String savePath;
    private volatile boolean isExit = false;

    private Runnable timerTask = new Runnable() {
        @Override
        public synchronized void run() {
            handler.sendEmptyMessage(UPDATE_TIME);
            handler.postDelayed(timerTask, 1000);
        }
    };

    private ScreenRecordUtils screenRecordUtils = new ScreenRecordUtils();
    private TimeManager timeManager = new TimeManager();

    @Override
    public void onCreate() {
        super.onCreate();
        init();
        handler = new Handler(getMainLooper()){
            @Override
            public void handleMessage(@NonNull Message msg) {
                super.handleMessage(msg);
                if(msg.what == UPDATE_MESSAGE_STOP_RESULT){
                    final int stopResult = msg.getData().getInt(STOP_RESULT, ScreenRecordUtils.StopListener.STOP_STATUS_FAIL);
                    switch (stopResult){
                        case ScreenRecordUtils.StopListener.STOP_STATUS_NO_RECORD:
                            binding.message.setText(R.string.message_no_record);
                            break;

                        case ScreenRecordUtils.StopListener.STOP_STATUS_SUCCESS:
                            binding.message.setText(R.string.message_save_success);
                            break;

                        case ScreenRecordUtils.StopListener.STOP_STATUS_FAIL:
                            binding.message.setText(R.string.message_save_fail);
                            break;

                        default:
                    }

                } else if(msg.what == UPDATE_TIME){
                    timeManager.autoAddSecond();
                    binding.recordTime.setText(String.format(
                            getResources().getString(R.string.record_time),
                            timeManager.getMinute(),
                            timeManager.getSecond()
                    ));

                } else if(msg.what == UPDATE_TIME_RESET){
                    timeManager.reset();
                    binding.recordTime.setText(String.format(
                            getResources().getString(R.string.record_time),
                            timeManager.getMinute(),
                            timeManager.getSecond()
                    ));

                } else if(msg.what == SHOW_VIDEO_SAVE_PATH){
                    if(savePath==null || "".equals(savePath)){
                        return;
                    }
                    Toast.makeText(FloatBarManager.this, "视频路径为： " + savePath, Toast.LENGTH_SHORT).show();
                }
            }
        };
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    private void init(){
        Log.d(TAG, "");
        linearLayout = new LinearLayout(this);
        final ViewGroup.LayoutParams linearParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        linearLayout.setLayoutParams(linearParams);
//        linearLayout.setBackgroundColor(Color.RED);

        binding = DataBindingUtil.inflate(LayoutInflater.from(this), R.layout.record_screen, linearLayout, true);


        wm = ((WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE));
        layoutParams = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT);
        layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        layoutParams.format = PixelFormat.RGBA_8888;
        layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
        layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
        layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
//        layoutParams.width = 250;
//        layoutParams.width = ScreenUtils.getScreenWidth()/6;
//        layoutParams.height = ScreenUtils.getScreenHeight()/10;
//        layoutParams.height = 85;
        layoutParams.x = 0;
        layoutParams.y = 0;
        disableAnimations(layoutParams);

        wm.addView(linearLayout, layoutParams);

        final IMoveControl moveControl = new MoveControl(wm, linearLayout, layoutParams, null);
        final MoveManager moveManager = new MoveManager(moveControl);
        linearLayout.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                moveManager.updateData(event);
                return false;
            }
        });

        binding.startOrStop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(!screenRecordUtils.isRecording()){
                    updateSavePath();
                    binding.startOrStop.setImageResource(R.drawable.stop);
                    binding.message.setText(R.string.message_recording);
                    screenRecordUtils.setSavePath(savePath);
                    screenRecordUtils.record();

                    handler.sendEmptyMessage(SHOW_VIDEO_SAVE_PATH);
                    handler.sendEmptyMessage(UPDATE_TIME_RESET);
                    handler.postDelayed(timerTask, 1000);
                } else {
                    binding.startOrStop.setImageResource(R.drawable.play);
                    binding.message.setText(R.string.message_stopping);
                    screenRecordUtils.stop();
                }
            }
        });

        binding.close.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                closeRelease();
            }
        });

        screenRecordUtils.setStopListener(new ScreenRecordUtils.StopListener() {
            @Override
            public void stopStatus(int result) {
                handler.sendEmptyMessage(SHOW_VIDEO_SAVE_PATH);
                handler.removeCallbacks(timerTask);

                if(isExit){
                    Log.d(TAG, "停止自己了喔：" + result);
                    stop();
                    return;
                }

                Log.d(TAG, "停止录制结果为：" + result);
                Message message = new Message();
                message.what = UPDATE_MESSAGE_STOP_RESULT;
                Bundle bundle = new Bundle();
                bundle.putInt(STOP_RESULT, result);
                message.setData(bundle);
                handler.sendMessage(message);
            }
        });
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() {
        closeRelease();
        super.onDestroy();
    }

    private void closeRelease(){
        if(screenRecordUtils.isRecording()){
            isExit = true;
            binding.message.setText(R.string.message_stopping);
            screenRecordUtils.stop();
        } else {
            handler.sendEmptyMessage(SHOW_VIDEO_SAVE_PATH);
            stop();
            handler.removeCallbacks(timerTask);
        }
    }

    private boolean isShow = false;
    private Point offsetPoint = new Point();

    private void updateSavePath(){
        savePath = SAVE_PATH_PRE + System.currentTimeMillis() + ".mp4";
    }

    private void stop(){
        if(linearLayout.isAttachedToWindow()){
            wm.removeView(linearLayout);
        }
        stopSelf();
    }

    private void hideTool(){
        if(!isShow){
            return;
        }

        layoutParams.x += offsetPoint.x;
        layoutParams.y += offsetPoint.y;
        linearLayout.clearAnimation();
        wm.updateViewLayout(linearLayout, layoutParams);
        offsetPoint.set(0, 0);

        handler.removeCallbacks(timerTask);
        isShow = false;
    }

    private void disableAnimations(ViewGroup.LayoutParams layoutParams) {
        try {
            int currentFlags = (Integer) layoutParams.getClass().getField("privateFlags").get(layoutParams);
            layoutParams.getClass().getField("privateFlags").set(layoutParams, currentFlags|0x00000040);
        } catch (Exception e) {
            //do nothing. Probably using other version of android
        }
    }

    private void hideBar(){
        if(linearLayout.isAttachedToWindow()){
            wm.removeView(linearLayout);
        }
    }

    private void showBar(){
        if(!linearLayout.isAttachedToWindow()){
            wm.addView(linearLayout, layoutParams);
        }
    }

    private void pressBtn(final int code){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    Instrumentation inst = new Instrumentation();
                    inst.sendKeyDownUpSync(code);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    private static class TimeManager {
        private int totalTime = 0;

        public int getMinute(){
            return totalTime/60;
        }

        public int getSecond(){
            return totalTime%60;
        }

        public void autoAddSecond(){
            totalTime++;
        }

        public void reset(){
            totalTime = 0;
        }
    }
}
